package com.cskaoyan.javase.oop1._6constructor;

/**
 * @description: Debug模式查看成员变量的赋值过程
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * > 目前给成员变量赋值有以下三种方式
 * - 默认初始化
 * - 显式赋值
 * - 构造器
 * > 在研究成员变量赋值顺序时，要把我“掐头去尾”的原则
 * - 成员变量永远先进行默认初始化，这一步会比其他赋值方式都要早，这是头
 * - 为了保证构造器赋值的正确性，构造器总是最后执行的，这是尾
 * - 头和尾之间执行显式赋值
 *
 * Debug模式查看成员变量的赋值：
 *      0.首先考虑类加载
 *      1.然后进入new对象的构造器，这时Variables窗口：
 *          this表示当前对象，此时它的成员变量都具有了默认值，它在任何其它赋值方式之前执行（对象的结构一存在，默认值就具备了，其它的任何赋值方式都是在默认值基础上完成的）
 *          p=parameter表示参数，对应构造器传入的实参
 *          对象中的f=field
 *      接下来程序的执行，会：
 *          a.如果构造器的第一行没有this指向别的构造器，那么会先从上到下执行成员变量的显式赋值，然后才执行构造器代码
 *          b.如果构造器的第一行有this指向别的构造器，那么会先跳转到this构造器，但是不会执行this构造器代码，而是：
 *               先从上到下执行成员变量的显式赋值
 *               随后再执行this构造器，最后再执行new对象的构造器
 *      2.new对象的构造器执行完毕，创建对象结束~
 *
 */
public class Demo2 {
    public static void main(String[] args) {
        //Student s2 = new Student(19);
        Student s = new Student(18, "马老师");
    }
}

class Student {
    int age = 10;
    String name = "张三";
    double a = 100;

    public Student(int age) {
        System.out.println("Student age");
        this.age = age;
    }

    public Student() {
    }

    public Student(int age, String name) {
        this(age);
        System.out.println("Student age,name");
        this.name = name;
    }
}